Android x Google Play Services #3 Location API で位置情報を取得する
Fused location provider な位置情報取得 API
Location API を使うとアプリに位置情報の機能をつけることができます。Google Play Services の Location API の位置情報取得には以下のような特徴があります。
シンプルな API
高精度にするか電力効率を優先するか、好みに応じてカスタマイズすることができます。ざっくりとした位置だけ把握したい場合は GPS を使わないでおく、などといった使いかたができます。
すぐに利用できる
すぐに直近の位置情報を取得することができます。
電力効率が良い
位置情報を取得する場所やセンサー情報を判断し、一番電力消費が少ないベストな方法を自動で選択して取得してくれます。
幅広いニーズに対応
バックグラウンドで定期的に位置情報を取得する場合など、さまざまなニーズに対応することができます。
ということで今回は位置情報の取得 (Fused location provider) を試してみたいと思います!
位置情報を取得する
まず AndroidManifest.xml にパーミッションを追加します。GPS を使いたい場合は ACCESS_FINE_LOCATION を使い GPS を使いたくない場合は ACCESS_COARSE_LOCATION を指定します。ちなみに ACCESS_FINE_LOCATION を指定すると ACCESS_COARSE_LOCATION も自動で許可されます。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
次に Activity.onCreate() で LocationClient インスタンスを生成します。このクラスが直接扱うクラスになります。第一引数は Context で、第二引数は API の接続ステータスを返す GooglePlayServicesClient.ConnectionCallbacks をセットし、第三引数には接続失敗時のコールバックである GooglePlayServicesClient.OnConnectionFailedListener をセットします。
mLocationClient = new LocationClient(this, mConnectionCallbacks, mOnConnectionFailedListener);
GooglePlayServicesClient.ConnectionCallbacks は以下のように実装します。実装する必要があるのは接続時に呼び出される onConnected() メソッドと切断時に呼び出される onDisconnected() メソッドです。
@Override public void onConnected(Bundle bundle) { Toast.makeText(self, "onConnected", Toast.LENGTH_LONG).show(); } @Override public void onDisconnected() { Toast.makeText(self, "onDisconnected", Toast.LENGTH_LONG).show(); }
GooglePlayServicesClient.OnConnectionFailedListener は onConnectionFailed() メソッドだけ実装します。
@Override public void onConnectionFailed(ConnectionResult connectionResult) { Toast.makeText(self, "onConnectionFailed", Toast.LENGTH_LONG).show(); }
ここまでで LocationClient のインスタンス化ができました。あとは LocationClient.connect() で API に接続し、 LocationClient.getLastLocation() で位置情報を取得します。以下では onStart() で API に接続して onStop() で切断しています。
@Override protected void onStart() { super.onStart(); mLocationClient.connect(); } @Override protected void onStop() { super.onStop(); mLocationClient.disconnect(); } private void getCurrentLocation() { if (mLocationClient.isConnected()) { Location location = mLocationClient.getLastLocation(); TextView tv = (TextView) findViewById(R.id.message); tv.setText(location.toString()); } else { Toast.makeText(self, "not connected", Toast.LENGTH_LONG).show(); } }
ここまでのコードをすべてまとめると以下のような感じになります。なお、前回解説した Google Play Services の API が使えるか確認する実装は割愛しています。
LocationActivity.java
package jp.classmethod.android.sample.locationapi; import android.app.Activity; import android.location.Location; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.location.LocationClient; public class LocationActivity extends Activity { private final LocationActivity self = this; private LocationClient mLocationClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_location); // LocationClient の生成 mLocationClient = new LocationClient(this, mConnectionCallbacks, mOnConnectionFailedListener); // 現在地を取得するボタン findViewById(R.id.current_location_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { getCurrentLocation(); } }); } @Override protected void onStart() { super.onStart(); // APIに接続 mLocationClient.connect(); } @Override protected void onStop() { super.onStop(); // APIから切断 mLocationClient.disconnect(); } private void getCurrentLocation() { // 接続されているときだけ現在地を取得 if (mLocationClient.isConnected()) { Location location = mLocationClient.getLastLocation(); TextView tv = (TextView) findViewById(R.id.message); tv.setText(location.toString()); } else { Toast.makeText(self, "not connected", Toast.LENGTH_LONG).show(); } } /** * 接続時・切断時のコールバック. */ private GooglePlayServicesClient.ConnectionCallbacks mConnectionCallbacks = new GooglePlayServicesClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { Toast.makeText(self, "onConnected", Toast.LENGTH_LONG).show(); } @Override public void onDisconnected() { Toast.makeText(self, "onDisconnected", Toast.LENGTH_LONG).show(); } }; /** * 接続失敗時のコールバック. */ private GooglePlayServicesClient.OnConnectionFailedListener mOnConnectionFailedListener = new GooglePlayServicesClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Toast.makeText(self, "onConnectionFailed", Toast.LENGTH_LONG).show(); } }; }
実行すると以下のように現在地を取得することができます!
まとめ
ということで現在位置の取得を試してみました。高精度にするか、消費電力を抑えるかはアプリによって異なってくるのでベストな指定をしておきたいところですね。